using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Diagnostics.Contracts;
using System.Windows;
using Konst3d.Efficiency.Suite;

namespace PEM
{
    internal partial class BuysViewModel
    {
        #region Commands

        public class AddBuyCommand : ICommand
        {
            #region Constructor

            public AddBuyCommand(BuysViewModel model)
            {
                Contract.Requires(model != null);

                _model = model;

                _model.SuiteOpened += OnSuiteChange;
                _model.SuiteClosed += OnSuiteChange;
                _model.SuiteCreated += OnSuiteChange;
                _model.SuiteDeleted += OnSuiteChange;
            }

            #endregion // Constructor

            #region ICommand Members

            public bool CanExecute(object parameter)
            {
                return _model.Suite != null;
            }

            public event System.EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                _model.AddBuy();
            }

            #endregion

            #region Event Handlers

            private void OnSuiteChange(ViewModelBase sender)
            {
                if (CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, EventArgs.Empty);
                }
            }

            #endregion Event Handlers

            #region Fields

            private BuysViewModel _model;

            #endregion // Fields
        }

        public class RemoveBuyCommand : ICommand
        {
            #region Constructor

            public RemoveBuyCommand(BuysViewModel model)
            {
                Contract.Requires(model != null);

                _model = model;
                _model.BuySelected += OnSuiteChange;
            }

            #endregion // Constructor

            #region ICommand Members

            public bool CanExecute(object parameter)
            {
                return _model.SelectedBuy != null;
            }

            public event System.EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                _model.RemoveBuy();
            }

            #endregion

            #region Event Handlers

            private void OnSuiteChange(ViewModelBase sender)
            {
                if (CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, EventArgs.Empty);
                }
            }

            #endregion Event Handlers

            #region Fields

            private BuysViewModel _model;

            #endregion // Fields
        }

        public class EditBuyCommand : ICommand
        {
            #region Constructor

            public EditBuyCommand(BuysViewModel model)
            {
                Contract.Requires(model != null);

                _model = model;
                _model.BuySelected += OnSuiteChange;
            }

            #endregion // Constructor

            #region ICommand Members

            public bool CanExecute(object parameter)
            {
                return _model.SelectedBuy != null;
            }

            public event System.EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                _model.EditBuy();
            }

            #endregion

            #region Event Handlers

            private void OnSuiteChange(ViewModelBase sender)
            {
                if (CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, EventArgs.Empty);
                }
            }

            #endregion Event Handlers

            #region Fields

            private BuysViewModel _model;

            #endregion // Fields
        }

        public class ChangeBuyStateCommand : ICommand
        {
            #region Constructor

            public ChangeBuyStateCommand(BuysViewModel model)
            {
                Contract.Requires(model != null);

                _model = model;
                _model.BuySelected += OnSuiteChange;
                _model.SelectedBuyStateChanged += OnSuiteChange;
            }

            #endregion // Constructor

            #region ICommand Members

            public bool CanExecute(object parameter)
            {
                return _model.SelectedBuy != null && _model.SelectedBuy.State != (BuyState)parameter;
            }

            public event System.EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                _model.ChangeBuyState((BuyState)parameter);
            }

            #endregion

            #region Event Handlers

            private void OnSuiteChange(ViewModelBase sender)
            {
                if (CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, EventArgs.Empty);
                }
            }

            #endregion Event Handlers

            #region Fields

            private BuysViewModel _model;

            #endregion // Fields
        }

        #endregion // Commands

        #region Commands Collection

        public class CommandsCollection
        {
            #region Properties

            public AddBuyCommand AddBuy
            {
                get;
                private set;
            }

            public RemoveBuyCommand RemoveBuy
            {
                get;
                private set;
            }

            public EditBuyCommand EditBuy
            {
                get;
                private set;
            }

            public ChangeBuyStateCommand ChangeBuyState
            {
                get;
                private set;
            }

            #endregion // Properties

            #region Constructor

            public CommandsCollection(BuysViewModel host)
            {
                Contract.Requires(host != null);

                AddBuy = new AddBuyCommand(host);
                RemoveBuy = new RemoveBuyCommand(host);
                EditBuy = new EditBuyCommand(host);
                ChangeBuyState = new ChangeBuyStateCommand(host);
            }

            #endregion // Constructor
        }

        #endregion // Commands Collection

        public void AddBuy()
        {
            Contract.Requires(Suite != null);

            if (_createEditBuyDlg.ShowDialog(_parentWindow))
            {
                Suite.Buys.Add(_createEditBuyDlg.BuyTitle,
                    _createEditBuyDlg.BuyDescription,
                    _createEditBuyDlg.BuySeverity,
                    _createEditBuyDlg.BuyPrice,
                    DateTime.Now,
                    _createEditBuyDlg.BuyDeadLine);

                UpdateBuyList();
            }
        }

        public void RemoveBuy()
        {
            Contract.Requires(Suite != null);
            Contract.Requires(SelectedBuy != null);

            if (MessageBox.Show(_parentWindow, "Are you sure, you wish to delete this buy?", "Delete buy?", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
            {
                Suite.Buys.Remove(SelectedBuy.ID);
                UpdateBuyList();
            }
        }

        public void EditBuy()
        {
            Contract.Requires(Suite != null);
            Contract.Requires(SelectedBuy != null);

            if (_createEditBuyDlg.ShowDialog(_parentWindow, SelectedBuy))
            {
                SelectedBuy.Title = _createEditBuyDlg.BuyTitle;
                SelectedBuy.Description = _createEditBuyDlg.BuyDescription;
                SelectedBuy.Severity = _createEditBuyDlg.BuySeverity;
                SelectedBuy.Price = _createEditBuyDlg.BuyPrice;
                SelectedBuy.DeadLine = _createEditBuyDlg.BuyDeadLine;

				UpdateBuyList(); // to keep consistent sorting... Buys.SignalItemChanged(SelectedBuy);
            }
        }

        public void ChangeBuyState(BuyState state)
        {
            Contract.Requires(Suite != null);
            Contract.Requires(SelectedBuy != null);
            
            SelectedBuy.State = state;
            Buys.NotifyItemChanged(SelectedBuy);

            if (SelectedBuyStateChanged != null)
            {
                SelectedBuyStateChanged(this);
            }

            if (StateFilter != BuyStateFilter.Any)
            {
                UpdateBuyList();
            }
        }
    }
}
